package com.codeoss.framework.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codeoss.framework.context.UserContext;
import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.converter.IConverter;
import com.codeoss.framework.converter.IConverterStore;
import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Query;
import com.codeoss.framework.data.metadata.Restrictions;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.metadata.TableData;
import com.codeoss.framework.data.store.ITableStore;
import com.codeoss.framework.response.WorkflowTaskManagementResponse;
import com.codeoss.framework.service.IWorkflowTaskManagementService;
import com.codeoss.framework.view.datasource.IDataSource;
import com.codeoss.framework.view.datasource.store.IDataSourceStore;
import com.codeoss.framework.view.model.SelectItem;
import com.codeoss.framework.view.util.LookupUtil;
import com.codeoss.framework.workflow.def.TaskNodeDef;
import com.codeoss.framework.workflow.def.WorkflowDef;
import com.codeoss.framework.workflow.store.IWorkflowStore;
import com.codeoss.module.ir.model.IrModel;
import com.codeoss.module.ir.model.IrWorkflow;
import com.codeoss.module.ir.service.IIrModelService;
import com.codeoss.module.ir.service.IIrWorkflowService;
import com.codeoss.module.workflow.model.WorkflowActivity;
import com.codeoss.module.workflow.model.WorkflowActivityInstance;
import com.codeoss.module.workflow.model.WorkflowProcess;
import com.codeoss.module.workflow.model.WorkflowTask;
import com.codeoss.module.workflow.service.IWorkflowActivityInstanceService;
import com.codeoss.module.workflow.service.IWorkflowActivityService;
import com.codeoss.module.workflow.service.IWorkflowProcessService;
import com.codeoss.module.workflow.service.IWorkflowTaskService;

@Service
public class WorkflowTaskManagementService implements IWorkflowTaskManagementService {
	@Autowired
	private IWorkflowTaskService workflowTaskService;
	@Autowired
	private IWorkflowActivityInstanceService workflowActivityInstanceService;
	@Autowired
	private IWorkflowProcessService workflowProcessService;
	@Autowired
	private IWorkflowStore workflowStore;
	@Autowired
	private IWorkflowActivityService workflowActivityService;
	@Autowired
	private IIrWorkflowService irWorkflowService;
	@Autowired
	private IIrModelService irModelService;
	@Autowired
	private ITableStore tableStore;
	@Autowired
	private IDataSourceStore dataSourceStore;
	@Autowired
	private LookupUtil lookupUtil;
	@Autowired
	private IConverterStore converterStore;
	@Override
	public WorkflowTaskManagementResponse init() {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse = new WorkflowTaskManagementResponse();
		UserContext userContext = UserContext.getCurrentUserContext();
		QueryWrapper<WorkflowTask> taskQuery = new QueryWrapper<WorkflowTask>();
		taskQuery.eq("owner", userContext.getUsername());
		taskQuery.eq("state", "DR");
		List<WorkflowTask> taskList = workflowTaskService.list(taskQuery);
		List<Map<String,Object>> taskMapList=new ArrayList<Map<String,Object>>();
		workflowTaskManagementResponse.setTaskList(taskMapList);
		fillTaskMapList(taskList,taskMapList);
		return workflowTaskManagementResponse;
	}
	@Override
	@Transactional
	public WorkflowTaskManagementResponse approve(Long taskId, String opinion) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		workflowTaskService.completeTask(taskId, "Y", opinion);
		return workflowTaskManagementResponse;
	}
	@Override
	@Transactional
	public WorkflowTaskManagementResponse reject(Long taskId, String opinion) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		workflowTaskService.completeTask(taskId, "N", opinion);
		return workflowTaskManagementResponse;
	}
	@Override
	@Transactional
	public WorkflowTaskManagementResponse back(Long taskId, String opinion) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		workflowTaskService.back(taskId, opinion);
		return workflowTaskManagementResponse;
	}
	@Override
	@Transactional
	public WorkflowTaskManagementResponse resubmit(Long taskId) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		workflowTaskService.resubmit(taskId);
		return workflowTaskManagementResponse;
	}
	@Override
	public WorkflowTaskManagementResponse getCount() {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		UserContext userContext=UserContext.getCurrentUserContext();
		QueryWrapper<WorkflowTask> taskQuery=new QueryWrapper<WorkflowTask>();
		taskQuery.eq("owner",userContext.getUsername());
		taskQuery.eq("state", "DR");
		long count=workflowTaskService.count(taskQuery);
		workflowTaskManagementResponse.setCount(count);
		return workflowTaskManagementResponse;
	}
	@Override
	public WorkflowTaskManagementResponse onPageChangeHandler(String pageType) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse=new WorkflowTaskManagementResponse();
		if(pageType.equals("todo")) {
			workflowTaskManagementResponse=init();
		}else if(pageType.equals("init")) {
			return onPageHandler(pageType, 1);
		}else if(pageType.equals("processed")) {
			return onPageHandler(pageType, 1);
		}
		return workflowTaskManagementResponse;
	}

	protected void fillTaskMapList(List<WorkflowTask> taskList,List<Map<String,Object>> taskMapList) {
		for (int i = 0; i < taskList.size(); i++) {
			WorkflowTask workflowTask = taskList.get(i);
			Map<String, Object> taskMap = new HashMap<String, Object>();
			taskMapList.add(taskMap);
			WorkflowActivityInstance workflowActivityInstance = workflowActivityInstanceService
					.getById(workflowTask.getWorkflowActivityInstanceId());
			WorkflowProcess workflowProcess = workflowProcessService
					.getById(workflowActivityInstance.getWorkflowProcessId());
			WorkflowActivity workflowActivity=workflowActivityService.getById(workflowActivityInstance.getWorkflowActivityId());
			WorkflowDef workflowDef = workflowStore.get(workflowProcess.getWorkflowWorkflowId());
			IrWorkflow irWorkflow=irWorkflowService.getIrWorkflowByCode(workflowDef.getCode());
			
			taskMap.put("processCode", workflowDef.getCode());
			taskMap.put("processName", workflowDef.getName());
			if(workflowProcess.getEndDate()!=null) {
				taskMap.put("processStateName", "已完成");
			}else {
				taskMap.put("processStateName", "进行中");
			}
			taskMap.put("bizKey", workflowProcess.getBizKey());
			taskMap.put("taskName", workflowActivity.getName());
			taskMap.put("taskCreteTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(workflowTask.getCreateDate()));
			taskMap.put("formCode", workflowDef.getFormCode());
			taskMap.put("mobileFormCode", workflowDef.getMobileFormCode());
			TaskNodeDef taskNodeDef=(TaskNodeDef)workflowDef.getNodeDefById(workflowActivity.getNodeId());
			taskMap.put("canUserInput",taskNodeDef.isCanUserInput());
			taskMap.put("canBack",taskNodeDef.isCanBack());
			taskMap.put("taskId",workflowTask.getId());
			Long irModelId=irWorkflow.getIrModelId();
			IrModel irModel=irModelService.getById(irModelId);
			String tableName=irModel.getTableName();
			Table table=tableStore.get(tableName);
			IDataSource dataSource=dataSourceStore.getDataSource(table.getAccessType());
			Query query=new Query();
			query.add(Restrictions.eq("id", Long.parseLong(workflowProcess.getBizKey())));
			YunContext yunContext=YunContext.getCurrentContext();
			TableData tableData=dataSource.select(yunContext, table, query);
			Map<String,Object> dataMap=tableData.getData().get(0);
			String displayColumnList[]=irWorkflow.getDisplayColumnList().split(",");
			for(int j=0;j<displayColumnList.length;j++) {
				Column column=table.getColumnByColumnName(displayColumnList[j]);
				Object value=dataMap.get(column.getColumnName());
				taskMap.put("doc_label_"+j, column.getName());
				if(value!=null) {
					if(column.getLookupInfo()!=null) {
						if(column.getLookupInfo().getDataSourceConfig()!=null) {
							List<SelectItem> selectItemList=lookupUtil.getSelectItemList(yunContext, column.getLookupInfo(),(Long)value);
							taskMap.put("doc_value_"+j, selectItemList.get(0).getName());
						}else if(column.getLookupInfo().getDictDef()!=null) {
							List<SelectItem> selectItemList=lookupUtil.getSelectItemList(yunContext,column.getLookupInfo());
							for(int k=0;k<selectItemList.size();k++) {
								if(selectItemList.get(k).getValue().equals(value)) {
									taskMap.put("doc_value_"+j, selectItemList.get(k).getName());
									break;
								}
							}
						}
					}else {
						IConverter converter=converterStore.getConverter(column.getDataType());
						String sValue=converter.convertObjectToString(value);
						taskMap.put("doc_value_"+j,sValue);
					}
				}else {
					taskMap.put("doc_value_"+j, "");
				}
			}
		}
	}

	@Override
	public WorkflowTaskManagementResponse onPageHandler(String pageType, int pageIndex) {
		// TODO Auto-generated method stub
		WorkflowTaskManagementResponse workflowTaskManagementResponse = new WorkflowTaskManagementResponse();
		if (pageType.equals("init")) {
			UserContext userContext = UserContext.getCurrentUserContext();
			QueryWrapper<WorkflowTask> taskQuery = new QueryWrapper<WorkflowTask>();
			taskQuery.eq("owner", userContext.getUsername());
			taskQuery.eq("state", "CO");
			taskQuery.eq("init_task", "1");
			taskQuery.orderByDesc("id");
			Page<WorkflowTask> page = new Page<WorkflowTask>(pageIndex, 5);
			IPage<WorkflowTask> pageResult = workflowTaskService.page(page, taskQuery);
			workflowTaskManagementResponse.setTotal(pageResult.getTotal());
			List<WorkflowTask> taskList = pageResult.getRecords();
			List<Map<String, Object>> taskMapList = new ArrayList<Map<String, Object>>();
			workflowTaskManagementResponse.setTaskList(taskMapList);
			fillTaskMapList(taskList, taskMapList);
		} else if (pageType.equals("processed")) {
			UserContext userContext = UserContext.getCurrentUserContext();
			QueryWrapper<WorkflowTask> taskQuery = new QueryWrapper<WorkflowTask>();
			taskQuery.eq("owner", userContext.getUsername());
			taskQuery.eq("state", "CO");
			taskQuery.isNull("init_task");
			taskQuery.orderByDesc("id");
			Page<WorkflowTask> page = new Page<WorkflowTask>(pageIndex, 5);
			IPage<WorkflowTask> pageResult = workflowTaskService.page(page, taskQuery);
			workflowTaskManagementResponse.setTotal(pageResult.getTotal());
			List<WorkflowTask> taskList = pageResult.getRecords();
			List<Map<String, Object>> taskMapList = new ArrayList<Map<String, Object>>();
			workflowTaskManagementResponse.setTaskList(taskMapList);
			fillTaskMapList(taskList, taskMapList);
		}
		return workflowTaskManagementResponse;
	}
}
